package cn.bonoon.kernel.menus;

import java.util.ArrayList;
import java.util.List;

/**
 * 这个对象生成后会被释放的，所以可以定义数据来处理
 * @author jackson
 *
 */
public class MenuViewBuilder implements MenuPrivilegeReader{

	private final ModuleManager moduleManager;
	
	private final MenuItemBuilder menuBuilder;
	
	private final List<String> modules = new ArrayList<>();
	
	private StringBuilder html;

	public MenuViewBuilder(ModuleManager moduleManager, MenuItemBuilder menuBuilder){
		this.moduleManager = moduleManager;
		this.menuBuilder = menuBuilder;
	}
	
	private boolean locked = false;
	
	public MenuViewBuilder add(String... keys){
		for(String key : keys){
			locked = add(key) || locked;
		}
		return this;
	}
	
	public boolean add(String key){
		if(null != key && !modules.contains(key)){
			boolean result = modules.add(key);
			locked = locked || result;
			return result;
		}
		return false;
	}
	
	@Override
	public boolean read(List<Object[]> items) {
		for(Object[] obj : items){
			//这里如果有定义操作权限的，需要进行合并
			String key = (String)obj[0];
			String mid = (String)obj[1];
			Number value = (Number)obj[2];
			Number actions = menuBuilder.get(mid);
			if(null != actions){
				value = actions.longValue() | value.longValue();
			}
			menuBuilder.put(mid, value);
			if(!locked && !modules.contains(key)) modules.add(key);
		}
		return false;
	}

	public MenuViewBuilder addRoles(ModulePrivilegeLoader loader, Long... rids){
		loader.rolePrivilege(this, rids);
		return this;
	}
	

	public MenuViewBuilder addAccounts(ModulePrivilegeLoader loader, Long aid){
		loader.accountPrivilege(this, aid);
		return this;
	}

	public MenuViewBuilder parse() {
		return parse(new StringBuilder());
	}
	
	private void internalParseModule(ModuleDefinition module, StringBuilder html){
		html.append("<div>");
		
		html.append(module.getName());
		
		if (menuBuilder.checkable()) {			
			html.append("<div style='color:#FF0000;font-size:11px;padding-left:5px;'>");
			html.append("（提示：“全选”-选中菜单以及所有子级菜单；“取消”-取消选中菜单以及所有子级菜单。）");
			html.append("</div>");
		}
		
		html.append("</div><ul>");
		
		for (ChannelDefinition ci : module.getChannels()) { // 循环该子系统下的所有频度
			
			String chaBuilder = menuBuilder.build(ci);
			
			StringBuilder menBuilder = visitMenus(ci.getMenus()); // 递归该频度下所有菜单
			boolean hasMenu = null != menBuilder && menBuilder.length() > 0;
			
			//TODO tabs
			StringBuilder tbsBuilder = menuBuilder.buildTabs(ci);//internalParseTabs(ci.getTabs());
			
			if((hasMenu || tbsBuilder.length() > 0) && chaBuilder.isEmpty()){
				chaBuilder = ci.getName();
			}
			
			if(chaBuilder.isEmpty()) continue;
			
			html.append("<li>").append(chaBuilder);
			if(hasMenu || tbsBuilder.length() > 0){
				menuBuilder.buildButton(html, ci);
			}
			
			html.append(menuBuilder.buildActions(ci));
			
			if(hasMenu){
				html.append("<ul>").append(menBuilder).append("</ul>");
			}
			
			if(tbsBuilder.length() > 0){
				html.append("<ul>").append(tbsBuilder).append("</ul>");
			}
			html.append("</li>");
		}
		html.append("</ul>");
		
	}

	public MenuViewBuilder parse(StringBuilder html) {
		this.html = html;
		for(String key : modules){
			ModuleDefinition md = moduleManager.module(key);
			if(null != md){
				html.append("<div>");
				internalParseModule(md, html);
				html.append("</div>");
			}
		}
		
		return this;
	}
	
	/** 是否有子菜单 */
	private StringBuilder visitMenus(List<MenuDefinition> menus) {
		if (null == menus || menus.isEmpty()) return null;
		
		StringBuilder html = new StringBuilder();
		
		for (MenuDefinition mi : menus) {
			//是否有菜单
			String menBuilder = menuBuilder.build(mi);//__checked(mi, checkboxCss);
			StringBuilder subBuilder = visitMenus(mi.getMenus());
			boolean hasSubmenu = null != subBuilder && subBuilder.length() > 0;
			
			if(hasSubmenu && menBuilder.isEmpty()){
				menBuilder = mi.getName();
			}
			
			if(menBuilder.isEmpty()) continue;
			
			html.append("<li>");
			html.append(menBuilder);
			if(hasSubmenu){
				//有子菜单，要出现全选按钮
				menuBuilder.buildButton(html, mi);
			}
			html.append(menuBuilder.buildActions(mi));
			
			if(hasSubmenu){
				html.append("<ul>").append(subBuilder).append("</ul>");
			}
			html.append("</li>");
		}
		
		return html;
	}

	@Override
	public String toString() {
		if(null == html) return "";
		return html.toString();
	}
}
